package com.vt.admin.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.vt.admin.api.dto.SysRoleListDto;
import com.vt.admin.api.dto.SysMenuTreeDto;
import com.vt.admin.api.dto.TreeNode;
import com.vt.admin.api.entity.SysRole;
import com.vt.admin.api.entity.SysRoleMenu;
import com.vt.admin.api.param.RoleMenuPermission;
import com.vt.admin.api.param.SysRoleListParam;
import com.vt.admin.api.vo.TreeUtil;
import com.vt.admin.mapper.SysRoleMapper;
import com.vt.common.core.util.R;
import com.vt.common.core.util.SnowflakeIdWorker;
import com.vt.common.security.service.CustomUser;
import com.vt.common.security.util.OrganizationUtil;
import com.vt.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@AllArgsConstructor
public class SysRoleService {

    SysRoleMapper mapper;
    OrganizationUtil organizationUtil;

    public Page<SysRoleListDto> list(SysRoleListParam param) {
        param.setManagerId(null);
        return mapper.list(param);
    }

    public R<SysRole> findOne(String id) {
        return new R(mapper.selectById(id));
    }

    public R<Boolean> save(SysRole role) {
        String uId = SecurityUtils.getUser().getId();
        Date d = new Date();

        role.setUpdater(uId)
                .setUpdateTime(d);

        if (StrUtil.isEmpty(role.getId())) {
            role.setCreater(uId)
                    .setCreateTime(d);
        }
        return new R(role.insertOrUpdate());
    }

    public R<List<SysMenuTreeDto>> findMenuPermission(String roleId) {
        CustomUser user = SecurityUtils.getUser();
        String userId = user.getUserType() == 1 ? user.getId() : null;
        List<SysMenuTreeDto> list = mapper.getMenuPermission(roleId, userId);

        SysMenuTreeDto root = new SysMenuTreeDto();
        root.setId("0");
        root.setName("所有模块");
        root.setParentId(null);

        list.add(root);
        list = TreeUtil.buildByRecursive(list, root.getId());

        //button list
        splitChildToBtn(list.get(0));
        return new R(list);
    }

    private void splitChildToBtn(SysMenuTreeDto node) {

        if (CollUtil.isEmpty(node.getChildren()))
            return;

        List<String> selectData = Lists.newArrayList();
        List<SysMenuTreeDto> bts = new ArrayList();
        SysMenuTreeDto ch;
        for (TreeNode obj : node.getChildren()) {
            ch = (SysMenuTreeDto) obj;

            if (null != ch.getType() &&
                    ch.getType() == 2) {
                bts.add(ch);
            }

            splitChildToBtn(ch);
            if (ch.getChecked())
                selectData.add(ch.getId());
        }

        node.getChildren().removeAll(bts);
        node.setButtonList(bts);
        node.setSelectData(selectData);
    }

    @Transactional
    public R<Boolean> delete(String id) {
        //清空角色对应的 user 关联
        mapper.deleteUserRole(id);

        //清空对应的 menu 关联
        mapper.deleteRoleMenu(id);

        //删除用户
        mapper.deleteById(id);
        return new R(Boolean.TRUE);
    }

    public R<Boolean> enable(SysRole role) {
        return new R(mapper.updateById(new SysRole().setId(role.getId()).setEnableStatus(role.getEnableStatus())));
    }

    @Transactional
    public R<Boolean> saveMenuPermission(RoleMenuPermission param) {
        mapper.deleteMenuPermission(param);

        String uId = SecurityUtils.getUser().getId();
        Date d = new Date();

        String[] ids = param.getIds();

        List<SysRoleMenu> list = new ArrayList();
        for (int i = 0, len = ids.length; i < len; i++) {
            list.add(new SysRoleMenu()
                    .setId(SnowflakeIdWorker.getId())
                    .setRoleId(param.getRoleId())
                    .setMenuId(ids[i])
                    .setCreater(uId)
                    .setUpdater(uId)
                    .setCreateTime(d)
                    .setUpdateTime(d));
        }

        mapper.batchInsertMenuPermission(list);
        return new R(Boolean.TRUE);
    }

    public R<List<SysRole>> findByCompany(String managerId) {
        managerId = organizationUtil.searchOrgMgCompany(managerId);
        List<SysRole> list = mapper.findRoleByCompanyId(managerId);
        return new R(list);
    }
}
